package xcoupon

import (
	"fmt"
	"time"

	"gitee.com/xiaoyutab/xgotool/optional/xcache"
	"gitee.com/xiaoyutab/xgotool/optional/xlog"
	"gitee.com/xiaoyutab/xgotool/xerror"
	"gitee.com/xiaoyutab/xgotool/xstring"
	"gorm.io/gorm"
)

// 领取优惠券
//
//	uid			用户ID
//	coupon_id	优惠券ID
func Receive(uid, coupon_id uint) error {
	if uid <= 0 {
		return xerror.New("未登录用户禁止领取")
	}
	inf, err := Info(coupon_id)
	if err != nil {
		return xlog.AE("优惠券主券未找到", err)
	}
	if inf.AvtivationStatus == 1 {
		return xerror.New("优惠券未找到-avtivation")
	}
	if inf.ChildOver != 2 {
		return xerror.New("优惠券未找到-child")
	}
	if inf.Examine != 3 {
		return xerror.New("优惠券未找到-examine")
	}
	if inf.StartType != 1 {
		// 指定时间段内可领取
		if xstring.ToTime(inf.StartTime).Unix() > time.Now().Unix() {
			return xerror.New("还未到该券可领取时间")
		}
		if xstring.ToTime(inf.EndTime).Unix() < time.Now().Unix() {
			return xerror.New("该优惠券领取时间已截至")
		}
	}
	if inf.Quota-inf.TakeCount <= 0 {
		return xerror.New("优惠券已发放完毕")
	}
	if _default.DB == nil {
		return xerror.New("数据库未连接")
	}
	if inf.PeopleCount > 0 && countByUids(uid, inf.Id) >= inf.PeopleCount {
		return xerror.New("优惠券已领取到限额")
	}
	// 校队完成，允许领取优惠券
	coupon_child := CouponChild{
		CouponId:       inf.Id,
		SerialNo:       xstring.RandomNo(_default.ChildSerialPre, 3),
		IsActivation:   1,
		UsedUid:        uid,
		ActivationTime: time.Now().Format(time.DateTime),
		UsedTime:       "1970-01-01 08:00:00",
		ExpirationTime: inf.ValidEndTime,
		CreatedAt:      time.Now().Format(time.DateTime),
		UpdatedAt:      time.Now().Format(time.DateTime),
	}
	if inf.ValidType == 2 {
		coupon_child.ExpirationTime = time.Now().AddDate(0, 0, int(inf.ValidDays)).Format(time.DateTime)
	}
	err = _default.DB.Table(_default.ChildCoupon).Create(&coupon_child).Error
	if err != nil {
		return xlog.AE("优惠券子券创建失败", err)
	}
	countAddByUids(uid, inf.Id)
	return nil
}

// 激活码兑换优惠券
//
//	uid			用户ID
//	coupon_code	优惠券激活码
func ReceiveCode(uid uint, coupon_code string) error {
	if uid <= 0 {
		return xerror.New("未登录用户禁止领取")
	}
	if _default.DB == nil {
		return xerror.New("数据库未连接")
	}
	// 根据激活码获取子优惠券详情
	coupon_child := CouponChild{}
	err := _default.DB.Table(_default.ChildCoupon).Where("activation_code", coupon_code).Where("is_activation", 0).Find(&coupon_child).Error
	if err != nil {
		return xlog.AE("激活码未找到", err)
	}
	if coupon_child.Id == 0 {
		return xerror.New("激活码未找到")
	}
	inf, err := Info(coupon_child.CouponId)
	if err != nil {
		return xlog.AE("优惠券主券未找到", err)
	}
	if inf.AvtivationStatus != 1 {
		return xerror.New("优惠券未找到-avtivation")
	}
	if inf.ChildOver != 2 {
		return xerror.New("优惠券未找到-child")
	}
	if inf.Examine != 3 {
		return xerror.New("优惠券未找到-examine")
	}
	// 校队完成，允许领取优惠券
	// coupon_child = CouponChild{
	// 	CouponId:       inf.Id,
	// 	SerialNo:       xstring.RandomNo(_default.ChildSerialPre, 3),
	// 	IsActivation:   1,
	// 	UsedUid:        uid,
	// 	ActivationTime: time.Now().Format(time.DateTime),
	// 	UsedTime:       "1970-01-01 08:00:00",
	// 	ExpirationTime: inf.ValidEndTime,
	// 	CreatedAt:      time.Now().Format(time.DateTime),
	// 	UpdatedAt:      time.Now().Format(time.DateTime),
	// }
	coupon_child.SerialNo = xstring.RandomNo(_default.ChildSerialPre, 3)
	coupon_child.IsActivation = 1
	coupon_child.UsedUid = uid
	coupon_child.ActivationTime = time.Now().Format(time.DateTime)
	coupon_child.ExpirationTime = inf.ValidEndTime
	coupon_child.UpdatedAt = time.Now().Format(time.DateTime)
	if inf.ValidType == 2 {
		coupon_child.ExpirationTime = time.Now().AddDate(0, 0, int(inf.ValidDays)).Format(time.DateTime)
	}
	err = _default.DB.Table(_default.ChildCoupon).Where("id", coupon_child.Id).Save(&coupon_child).Error
	if err != nil {
		return xlog.AE("优惠券子券存储失败", err)
	}
	countAddByUids(uid, inf.Id)
	return nil
}

// 获取用户领取优惠券条数
//
//	uid	用户ID
func countByUids(uid, cid uint) uint {
	if uid <= 0 {
		return 0
	}
	cache_key := xcache.Key("xcoupon.count.by.uids", uid, cid)
	if xcache.Exists(cache_key) {
		return xstring.ToUint(xcache.GetString(cache_key))
	}
	var count int64
	err := _default.DB.Table(_default.ChildCoupon).Where("used_uid", uid).Where("coupon_id", cid).Count(&count).Error
	if err != nil {
		xlog.Alert("用户优惠券领取条数查询失败", err)
		return 0
	}
	xcache.SetStruct(cache_key, fmt.Sprintf("%d", count))
	return uint(count)
}

// 优惠券领取优惠券领取数量+1
func countAddByUids(uid, cid uint) {
	// 缓存+1
	xcache.Set(xcache.Key("xcoupon.count.by.uids", uid, cid), fmt.Sprintf("%d", countByUids(uid, cid)+1))
	// 已领取数量+1
	_default.DB.Table(_default.CouponTable).Where("id", cid).Update("take_count", gorm.Expr("`take_count` + ?", 1))
}
